package com.agileai.hotweb.common;

import java.util.HashMap;

import javax.sql.DataSource;

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.agileai.common.AppConfig;

public class BeanFactory {
	public final static String DfaultDatasourceId = "dataSource";
	
	private static HashMap<ClassLoader,BeanFactory> beanFactoryCache = new HashMap<ClassLoader,BeanFactory>();
	
	private ApplicationContext context = null;
	private ClassLoader beanClassLoader = null;
	private ClassLoader beanContextClassLoader = null;
	
	private BeanFactory(){}
	
	public synchronized static BeanFactory instance(){
		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		BeanFactory instance = beanFactoryCache.get(classLoader);
		if (instance == null){
			try {
				instance = (BeanFactory)classLoader.loadClass("com.agileai.hotweb.common.BeanFactory").newInstance();			
				beanFactoryCache.put(classLoader, instance);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return instance;
	}
	
	public static void init(String serviceConfigLocation){
		BeanFactory instance = instance();
		if (instance.context == null){
			String[] configs = serviceConfigLocation.split(",");
			if (instance.beanContextClassLoader != null){
				instance.context = new ClassPathXmlApplicationContext();
				((ClassPathXmlApplicationContext)instance.context).setClassLoader(instance.beanContextClassLoader);
				((ClassPathXmlApplicationContext)instance.context).setConfigLocations(configs);
				((ClassPathXmlApplicationContext)instance.context).refresh();
			}else{
				instance.context = new ClassPathXmlApplicationContext(configs);
			}
		}
	}
	
	public Object getBean(String beanId){
		if (beanClassLoader != null){
			DefaultListableBeanFactory springBeanFactory = (DefaultListableBeanFactory)context.getAutowireCapableBeanFactory();
			springBeanFactory.setBeanClassLoader(beanClassLoader);
		}
		return this.context.getBean(beanId);
	}
	public DataSource getDataSource(){
		DataSource result = (DataSource)getBean(DfaultDatasourceId);
		return result;
	}
	
	public DataSource getDataSource(String datasoureId){
		DataSource result = (DataSource)getBean(datasoureId);
		return result;
	}
	
	public AppConfig getAppConfig(String configId){
		AppConfig result = (AppConfig)getBean(configId);
		return result;
	}
	public AppConfig getAppConfig(){
		AppConfig result = (AppConfig)getBean("appConfig");
		return result;
	}
	
	public void setBeanClassLoader(ClassLoader beanClassLoader) {
		this.beanClassLoader = beanClassLoader;
	}

	public ClassLoader getBeanContextClassLoader() {
		return beanContextClassLoader;
	}

	public void setBeanContextClassLoader(ClassLoader beanContextClassLoader) {
		this.beanContextClassLoader = beanContextClassLoader;
	}
	
}
